package ru.fadeev.crammer;

import java.awt.event.KeyEvent;
import java.io.File;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.swing.JTable;
import javax.swing.KeyStroke;

/**
 * Utils class contains several useful functions that used in different
 * parts of Crammer program.
 * @author Konstantin Fadeyev
 *
 */
public class Utils {
	public final static int NO_MARK = 0;
	public final static int DOT_MARK = 1;
	public final static int BOLD_MARK = 2;
	
	
	/**
	 * Returns extension for given file
	 * @param file object of File
	 * @return extension string
	 */
	public static String getExtension(File file) {
		String extension = null;
        String s = file.getName();
        int i = s.lastIndexOf('.');

        if (i > 0 &&  i < s.length() - 1) {
        	extension = s.substring(i+1).toLowerCase();
        }
        return extension;
	}
	
	
	/**
	 * Function replace all entries of 'word' in the phrase by '...'.
	 * If word consists of several items (word like 'wake up'), every item 
	 * will be replaced by '...'. 
	 * @param phrase Phrase containing word to replace
	 * @param word Word to replace
	 * @return Phrase that has all entries of word replaces by '...' 
	 */
	public static String markWord(String phrase, String word, int markType) {
		String result = new String();
		String[] tokens = word.trim().split("\\s+");
		if(tokens.length ==0)
			return phrase;
		
		int currentIndex = 0;
		int nextMatchStartIndex = 0;
		String subResult = "";
		boolean matched = true;
		while(matched) {
			nextMatchStartIndex = currentIndex;
			result = result + subResult;
			subResult = "";
			for(int i=0; i< tokens.length; i++)	{
				// if word ends by, "e" we cut "e"
				if(tokens[i].length() >=2) {
					String lastLetter = 
						tokens[i].substring(tokens[i].length()-1, tokens[i].length());
					String nextToLastLetter = 
						tokens[i].substring(tokens[i].length()-2, tokens[i].length()-1);
					if(lastLetter.equals("e") 
							&& "bcdfghklmnpqrstvwxz".contains(nextToLastLetter)) {
						tokens[i] = tokens[i].substring(0,tokens[i].length()-1);
					}
				}
				Pattern p = Pattern.compile("\\b" + tokens[i] + 
					"[a-zA-Z]*", Pattern.CASE_INSENSITIVE);
				Matcher matcher = p.matcher(phrase);
				if(matcher.find(currentIndex)) {
					String replace;
					switch(markType) {
					case DOT_MARK:
						replace = "...";
						break;
					case BOLD_MARK:
						replace = "<b>" + matcher.group() + "</b>";
						break;
					default:
						replace = matcher.group();
					}
					subResult = subResult + 
							phrase.substring(currentIndex, matcher.start()) + replace;
					currentIndex = matcher.end();
				} else {
					matched = false;
					break;
				}
			}
		}
		result = result + phrase.substring(nextMatchStartIndex, phrase.length());
		return result;		
	}
	
	
	/**
	 * Returns string that prepared to save to DB. Preparation consists of
	 * masking apostrophe and cutting to custom length.
	 * @param string string to prepare
	 * @param len db field max length
	 * @return prepared string
	 */
	public static String prep(String string, int len) {
		String result = string.replaceAll("'","''");
		if(result.length() > len) {			
			result = result.substring(0, len);
			if(result.charAt(result.length()-1) == '\'' && 
					result.charAt(result.length()-2) != '\'') {
				result = result + "'";
			}
		}
		return result;
	}
	
	
	/**
	 * Retursn human readable string representation for a given keyStroke.
	 * @param keyStroke object of KeyStroke
	 * @return  string representation for a keyStroke
	 */
	public static String keyStrokeToString(KeyStroke keyStroke) {
		if(keyStroke.getModifiers() == 0) {
			return KeyEvent.getKeyText(keyStroke.getKeyCode());
		} else {
			return KeyEvent.getKeyModifiersText(keyStroke.getModifiers()) + "+" +
			KeyEvent.getKeyText(keyStroke.getKeyCode());
		}
	}
	
		
	/**
	 * When user's editing some word and in that moment does some action 
     * with this word, actions will be done with value that was before edit.
     * So finishTableEditing function updates value so all changes with 
     * the word would be applied to value that user sees on the screen.
	 * @param table table, functions finishes editing in
	 */
    public static void finishTableEditing(JTable table) {
    	if(table.isEditing()) {
        	int[] currentRowIndices = table.getSelectedRows();
        	int[] currentColumnIndices = table.getSelectedColumns();   	
    		
        	table.getCellEditor().stopCellEditing();
    		
    		if(currentRowIndices.length > 0)
    			for(int i=0; i<currentRowIndices.length; i++)
    				table.addRowSelectionInterval(currentRowIndices[i], 
    							currentRowIndices[i]);

    		if(currentColumnIndices.length > 0)
    			for(int i=0; i<currentColumnIndices.length; i++)
    				table.addColumnSelectionInterval(currentColumnIndices[i], 
    							currentColumnIndices[i]);
    	}
    }
}
